Rx 的世界基本上是由下述二種物件所組成。
- Observable (Sequence): 發出事件的對象
- Observer: 收到事件要處理的對象
而這些物件再透過 transform, filter, combine 共同組合強大的功能。
Rx 介紹
Observable
常用到的 Observable 建立:
- empty()
- just()
- from()
- create()
1 | let s = Observable<Int>.create { observer in |
Subject
是 Observable 也是 Observer,常用的有下述:
- PublishSubject: 訂閱後進行發送
- ReplaySubject: 訂閱後會補訂閱前發送的事件,有 size 限制
- BehaviorSubject: 給定一個預設值,訂閱後會補最後一個事件,如果沒有最後的事件則發送預設值
Transformer
轉換,將一個 Sequence 轉成另一個 Sequence
- map:將傳入的參數做 一次轉換, input 和 output 的資料型別不同
1 | Observable.of(1, 2, 3) |
- flatMap:將傳入的參數轉成 Observable 再傳出去,假設有一個二階的資料,先傳入第一階的資料,然後在 flatMap 中把第二階的資料作為 Observable 回傳,如此一來就會把二階的資料 拍平 成一階
Filter
- distinctUntilChanged: 忽略與上次的觸發事件相同的值,如果這個事件是比較花費資源的計算建議要加入該 filter
1 | let inputValid = textField.rx_text |
Combination
- combineLatest:同時監看多個 sequence, 當其中一個 sequence 觸發時將這些 sequence 合併送出
1 | let s = Observable<String>.combineLatest(textField1.rx_text, textField2.rx_text) { |
UI interactive
一個 UI control 要綁定一個 observable 時:
1 | observable.bindTo(ctrl.rx_xxx) |
當 model 資料變更時要觸發 View 更新:
1 | observable.onNext(xxx) |
UIButton 按下時,讀入 UITextField 內的值進行處理
簡單版:
1 | let allText = Observable.combineLatest(textField1.rx_text, textField2.rx_text) { |
MVVM 版:
ViewModel:
1 | class ViewModel { |
ViewController:
1 | class ViewController { |
一個服務在背景運作,並持續透過一個 callback (closure) 發出命令,可以作一個 Rx 的 Wrapper ,更可以直接綁定在 UI 上
ViewModel:
1 | class TestViewModel { |
ViewController:
1 | var test = TestViewModel() |
綁定一個文字方塊,為了避免用戶輸入時一直拿到值進行運行,可以透過 debounce(throttle) 來處理
1 | textField.rx_text |